package com.ddz.implementation;

import java.io.IOException;
import java.io.InputStream;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.Rect;

import com.ddz.interfaces.IImage;

public class Graphics {
	public static enum ImageFormat {
		ARGB8888, ARGB4444, RGB565
	}

	AssetManager mAssets;
	Bitmap mFrameBuffer;
	Canvas mCanvas;
	Paint mPaint;
	Rect mSrcRect = new Rect();
	Rect mDstRect = new Rect();

	public Graphics(AssetManager _assets, Bitmap _frameBuffer) {
		mAssets = _assets;
		mFrameBuffer = _frameBuffer;
		mCanvas = new Canvas(_frameBuffer);
		mPaint = new Paint();
	}

	// Create a new IImage object
	// First parameter is the file path/name to be loaded
	// Second parameter is the Image format used in the image
	public IImage newImage(String fileName, ImageFormat format) {
		Config config = null;
		if (format == ImageFormat.RGB565)
			config = Config.RGB_565;
		else if (format == ImageFormat.ARGB4444)
			config = Config.ARGB_4444;
		else
			config = Config.ARGB_8888;

		Options options = new Options();
		options.inPreferredConfig = config;

		InputStream in = null;
		Bitmap bitmap = null;
		try {
			in = mAssets.open(fileName);
			bitmap = BitmapFactory.decodeStream(in, null, options);
			if (bitmap == null)
				throw new RuntimeException("Couldn't load bitmap from asset '"
						+ fileName + "'");
		} catch (IOException e) {
			throw new RuntimeException("Couldn't load bitmap from asset '"
					+ fileName + "'");
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}

		if (bitmap.getConfig() == Config.RGB_565)
			format = ImageFormat.RGB565;
		else if (bitmap.getConfig() == Config.ARGB_4444)
			format = ImageFormat.ARGB4444;
		else
			format = ImageFormat.ARGB8888;

		return new Image(bitmap, format);
	}

	// Clears the screen into a certain color
	public void clearScreen(int color) {
		mCanvas.drawRGB((color & 0xff0000) >> 16, (color & 0xff00) >> 8,
				(color & 0xff));
	}

	// draws a line from x-y to another x2-y2
	public void drawLine(int x, int y, int x2, int y2, int color) {
		mPaint.setColor(color);
		mCanvas.drawLine(x, y, x2, y2, mPaint);
	}

	// draws a line from one POINT to another
	public void drawLine(Point p1, Point p2, int color) {
		mPaint.setColor(color);
		mCanvas.drawLine(p1.x, p1.y, p2.x, p2.y, mPaint);
	}

	// draws a rectangle from position x-y with width and height
	public void drawRect(int x, int y, int width, int height, int color) {
		mPaint.setColor(color);
		mPaint.setStyle(Style.FILL);
		mCanvas.drawRect(x, y, x + width - 1, y + height - 1, mPaint);
	}

	// draws a rectangle from Point with width and height
	public void drawRect(Point p, int width, int height, int color) {
		mPaint.setColor(color);
		mPaint.setStyle(Style.FILL);
		mCanvas.drawRect(p.x, p.y, p.x + width, p.y + height, mPaint);
	}

	// Fill the entire canvas' bitmap (restricted to the current clip)
	// with the specified ARGB color
	public void drawARGB(int a, int r, int g, int b) {
		mPaint.setStyle(Style.FILL);
		mCanvas.drawARGB(a, r, g, b);
	}

	// Draw string passed in at position x-y using Paint to define
	// color and brush
	public void drawString(String text, int x, int y, Paint paint) {
		mCanvas.drawText(text, x, y, paint);
	}

	// draws an image from position x-y starting at the images srcX-srcY
	// and going over to the images srcWidth-srcHeight
	public void drawImage(IImage _image, int x, int y, int srcX, int srcY,
			int srcWidth, int srcHeight) {
		mSrcRect.left = srcX;
		mSrcRect.top = srcY;
		mSrcRect.right = srcX + srcWidth;
		mSrcRect.bottom = srcY + srcHeight;

		mDstRect.left = x;
		mDstRect.top = y;
		mDstRect.right = x + srcWidth;
		mDstRect.bottom = y + srcHeight;

		mCanvas.drawBitmap(((Image) _image).mBitmap, mSrcRect, mDstRect, null);
	}

	// draws an image from position x-y with images width and height
	public void drawImage(IImage _image, int x, int y) {
		mCanvas.drawBitmap(((Image) _image).mBitmap, x, y, null);
	}

	// draws an image from point starting at the images srcX-srcY
	// and going over to the images srcWidth-srcHeight
	public void drawImage(IImage _image, Point p, int srcX, int srcY,
			int srcWidth, int srcHeight) {
		mSrcRect.left = srcX;
		mSrcRect.top = srcY;
		mSrcRect.right = srcX + srcWidth;
		mSrcRect.bottom = srcY + srcHeight;

		mDstRect.left = p.x;
		mDstRect.top = p.y;
		mDstRect.right = p.x + srcWidth;
		mDstRect.bottom = p.y + srcHeight;

		mCanvas.drawBitmap(((Image) _image).mBitmap, mSrcRect, mDstRect, null);
	}

	// draws an image from point with images width and height
	public void drawImage(IImage _image, Point p) {
		mCanvas.drawBitmap(((Image) _image).mBitmap, p.x, p.y, null);
	}

	public void drawScaledImage(IImage _image, int x, int y, int width,
			int height, int srcX, int srcY, int srcWidth, int srcHeight) {

		mSrcRect.left = srcX;
		mSrcRect.top = srcY;
		mSrcRect.right = srcX + srcWidth;
		mSrcRect.bottom = srcY + srcHeight;

		mDstRect.left = x;
		mDstRect.top = y;
		mDstRect.right = x + width;
		mDstRect.bottom = y + height;

		mCanvas.drawBitmap(((Image) _image).mBitmap, mSrcRect, mDstRect, null);
	}

	// returns the current framebuffers width
	public int getWidth() {
		return mFrameBuffer.getWidth();
	}

	// returns the current framebuffers height
	public int getHeight() {
		return mFrameBuffer.getHeight();
	}
}
